allow the webhook agent to loop over returned results if the payload_path points to an array

Andrew Cantino 10 years ago
parent
commit
f5ff481fc9
2 changed files with 23 additions and 9 deletions
  1. 8 4
      app/models/agents/webhook_agent.rb
  2. 15 5
      spec/models/agents/webhook_agent_spec.rb

+ 8 - 4
app/models/agents/webhook_agent.rb

@@ -20,13 +20,14 @@ module Agents
20 20
           * `expected_receive_period_in_days` - How often you expect to receive
21 21
             events this way. Used to determine if the agent is working.
22 22
           * `payload_path` - JSONPath of the attribute in the POST body to be
23
-            used as the Event payload.
23
+            used as the Event payload.  If `payload_path` points to an array,
24
+            Events will be created for each element.
24 25
       MD
25 26
     end
26 27
 
27 28
     event_description do
28 29
       <<-MD
29
-        The event payload is base on the value of the `payload_path` option,
30
+        The event payload is based on the value of the `payload_path` option,
30 31
         which is set to `#{interpolated['payload_path']}`.
31 32
       MD
32 33
     end
@@ -34,7 +35,8 @@ module Agents
34 35
     def default_options
35 36
       { "secret" => "supersecretstring",
36 37
         "expected_receive_period_in_days" => 1,
37
-        "payload_path" => "payload"}
38
+        "payload_path" => "some_key"
39
+      }
38 40
     end
39 41
 
40 42
     def receive_web_request(params, method, format)
@@ -42,7 +44,9 @@ module Agents
42 44
       return ["Please use POST requests only", 401] unless method == "post"
43 45
       return ["Not Authorized", 401] unless secret == interpolated['secret']
44 46
 
45
-      create_event(:payload => payload_for(params))
47
+      [payload_for(params)].flatten.each do |payload|
48
+        create_event(payload: payload)
49
+      end
46 50
 
47 51
       ['Event Created', 201]
48 52
     end

+ 15 - 5
spec/models/agents/webhook_agent_spec.rb

@@ -3,27 +3,37 @@ require 'spec_helper'
3 3
 describe Agents::WebhookAgent do
4 4
   let(:agent) do
5 5
     _agent = Agents::WebhookAgent.new(:name => 'webhook',
6
-                                      :options => { 'secret' => 'foobar', 'payload_path' => 'payload' })
6
+                                      :options => { 'secret' => 'foobar', 'payload_path' => 'some_key' })
7 7
     _agent.user = users(:bob)
8 8
     _agent.save!
9 9
     _agent
10 10
   end
11
-  let(:payload) { {'some' => 'info'} }
11
+  let(:payload) { {'people' => [{ 'name' => 'bob' }, { 'name' => 'jon' }] } }
12 12
 
13 13
   describe 'receive_web_request' do
14 14
     it 'should create event if secret matches' do
15 15
       out = nil
16 16
       expect {
17
-        out = agent.receive_web_request({ 'secret' => 'foobar', 'payload' => payload }, "post", "text/html")
17
+        out = agent.receive_web_request({ 'secret' => 'foobar', 'some_key' => payload }, "post", "text/html")
18 18
       }.to change { Event.count }.by(1)
19 19
       expect(out).to eq(['Event Created', 201])
20 20
       expect(Event.last.payload).to eq(payload)
21 21
     end
22 22
 
23
+    it 'should be able to create multiple events when given an array' do
24
+      out = nil
25
+      agent.options['payload_path'] = 'some_key.people'
26
+      expect {
27
+        out = agent.receive_web_request({ 'secret' => 'foobar', 'some_key' => payload }, "post", "text/html")
28
+      }.to change { Event.count }.by(2)
29
+      expect(out).to eq(['Event Created', 201])
30
+      expect(Event.last.payload).to eq({ 'name' => 'jon' })
31
+    end
32
+
23 33
     it 'should not create event if secrets dont match' do
24 34
       out = nil
25 35
       expect {
26
-        out = agent.receive_web_request({ 'secret' => 'bazbat', 'payload' => payload }, "post", "text/html")
36
+        out = agent.receive_web_request({ 'secret' => 'bazbat', 'some_key' => payload }, "post", "text/html")
27 37
       }.to change { Event.count }.by(0)
28 38
       expect(out).to eq(['Not Authorized', 401])
29 39
     end
@@ -31,7 +41,7 @@ describe Agents::WebhookAgent do
31 41
     it "should only accept POSTs" do
32 42
       out = nil
33 43
       expect {
34
-        out = agent.receive_web_request({ 'secret' => 'foobar', 'payload' => payload }, "get", "text/html")
44
+        out = agent.receive_web_request({ 'secret' => 'foobar', 'some_key' => payload }, "get", "text/html")
35 45
       }.to change { Event.count }.by(0)
36 46
       expect(out).to eq(['Please use POST requests only', 401])
37 47
     end